package cn.ztydata.teachingsystem.heaven.dao.redis;

import cn.ztydata.teachingsystem.heaven.entity.KnowledgePoint;
import cn.ztydata.teachingsystem.heaven.entity.test.Test;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Repository;

import java.util.Set;

/**
 * 作业或测试考点
 * Created by fanruiping on 2015/3/20.
 */
@Repository
public class TestKpDao extends BaseRedisDao {
    /**
     * 获取作业或测试包含的考点编号集合
     * @param testId
     * @return Set
     *
     * @author fanruiping
     * @since 2015-03-20
     */
    public Set<Long> getKpIds(long testId){
        //获取Set操作
        SetOperations<String, Long> setOperations = redisTemplate.opsForSet();

        logger.debug("return test kpIds");

        return setOperations.members(KeyUtils.testKp(testId));
    }

    /**
     * 保存作业/测试与知识点的关系
     * @param test 作业/测试实体
     * @return Boolean
     *
     * @author fanruiping
     * @since 215-03-21
     */
    public Boolean addKp(final Test test) {
        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            @Override
            public Boolean execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                //获取Set操作
                SetOperations<String, Long> setOperations = operations.opsForSet();

                logger.debug("循环作业考点列表:KnowledgePoint kp : test.getKnowledgePoints()");
                for (KnowledgePoint kp : test.getKnowledgePoints()){
                    //保存作业与知识点的关系
                    setOperations.add(KeyUtils.testKp(test.getId()), kp.getId());
                }

                operations.exec();
                return true;
            }
        };

        logger.debug("return 新增资源关键字关系执行结果");

        return (Boolean)redisTemplate.execute(sessionCallback);
    }

    /**
     * 删除作业与知识点的关系(一个)
     * @param kpId 知识点编号
     * @param testId 作业编号
     * @return Boolean
     *
     * @author fanruiping
     * @since 2015-03-21
     */
    public Boolean deleteKp(final long kpId, final long testId) {
        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            @Override
            public Boolean execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                //获取Set操作
                SetOperations<String, Long> setOperations = operations.opsForSet();

                //删除作业与知识点的关系
                setOperations.remove(KeyUtils.testKp(testId), kpId);

                operations.exec();
                return true;
            }
        };

        logger.debug("execute delete resource kp");

        return (Boolean)redisTemplate.execute(sessionCallback);
    }

    /**
     * 删除作业的所有知识点
     * @param id
     * @return Boolean
     *
     * @author fanruiping
     * @since 2015-03-21
     */
    public Boolean deleteKps(final Long id) {
        //获取作业的所有知识点编号集合
        final Set<Long> kpIds = this.getKpIds(id);

        if(kpIds.isEmpty()){
            logger.debug("kpId set is empty:kpIds.isEmpty()");

            return true;
        }

        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            @Override
            public Boolean execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                //获取Set操作
                SetOperations<String, Long> setOperations = operations.opsForSet();

                logger.debug("循环知识点编号集合:Long kpId : kpIds");
                for(Long kpId : kpIds){
                    //删除资源与知识点的关系
                    setOperations.remove(KeyUtils.testKp(id), kpId);
                }

                operations.exec();
                return true;
            }
        };

        logger.debug("返回删除作业考点执行结果");

        return (Boolean)redisTemplate.execute(sessionCallback);
    }
}
